<?php
//这是新建的home 控制器,路由找到home后,就会进入到这个文件,执行各种方法  http://yii.abc.com/index.php?r=home/index

//声明命名空间
namespace app\controllers;
date_default_timezone_set('Asia/Shanghai');

use app\models\Download;
use app\models\Project;
use app\models\Upload;
use app\models\User;
use Yii;
//use yii\filters\AccessControl;
use app\models\Articale;
use app\models\Category;
use app\models\UploadForm;

use yii\web\Controller; //没有这一句会报命名空间错误
use yii\web\Request;  //需要这个控制器,路由才能进入到这里
use yii\web\UploadedFile; //这个组件是负责上传文件的
use yii\data\Pagination;
use function Couchbase\defaultDecoder;

//这是分页的类

//use yii\web\Response;
//use yii\filters\VerbFilter;
//use app\models\LoginForm;
//use app\models\ContactForm;

//use app\libraries\filters\AccessControl;  //这是控制登录,必须登录才能访问

set_time_limit(0);


class HomeController extends Controller { //自定义控制器要继承父控制器

    public $enableCsrfValidation = false; //不加这条会报400
    public $layout='home'; //自定义头部和脚部文件

    //public function behaviors()
    //{
    //    return [
    //        'access' => [
    //            'class' => AccessControl::className(),
    //            'rules' => [
    //                [
    //                    'allow' => true,
    //                    'roles' => ['@'],
    //                ],
    //            ],
    //        ],
    //    ];
    //}

    public function actionIndex(){  //路由的前面要加上action,并且用驼峰命名
        $uploads=Upload::find();
        $model=new UploadForm();
        $projects=Project::find()->all();
        $pages=new Pagination(['totalCount'=>$uploads->count(), //http://www.manks.top/yii2_linkpager_pagination.html 分页 https://www.yiichina.com/tutorial/774
            'validatePage' => false,
        ]);
        $uploads=$uploads->offset($pages->offset)->limit($pages->limit)->all();
        $data=["uploads"=>$uploads,"pages"=>$pages,"model"=>$model,"projects"=>$projects];
        return $this->render('index_5',$data);
    }
    public function actionDologin()
    {
        $request=\Yii::$app->request;

        $user=$request->post('name','张三');  //张三是默认值,当没有
        $passwd=$request->post('password','123');
        //p($passwd);
        //p(md5($passwd));
        $userObj=User::find()->Where(['username'=>$user,'password'=>md5($passwd)])->all();

        if($userObj){
            $session = \Yii::$app->session;
            $session->set('user', $user);  //建立session

            return $this->redirect('index.php?r=home/index');
        }else{
            $this->layout = false;
            $alert=1;
            $data=["alert"=>$alert];
            return $this->render('login',$data);
        }

    }
    public function actionLogin()
    {
        $this->layout = false;
        return $this->render('login');
    }
    public function actionLogout()
    {
        $session = \Yii::$app->session;
        $session->remove('user'); //销毁session
        return $this->redirect('index.php?r=home/login');
    }
    public function actionAddfile() //这个是页面上传文件的过程
    {
        //$request=\Yii::$app->request;
        //$user=$request->post('name','张三');  //张三是默认值,当没有
        //$passwd=$request->post('password','123');
        //curl -F "file=@./2.mp4; filename='2.mp4'" -H "Content-filename:2.mp4" http://yii.abc.com/index.php?r=home/addfile
        //curl -F "myfile1=@3.mp4"  "http://yii.abc.com/index.php?r=home/addfile&username=ggc&password=123456"
        //curl -F "myfile1=@3.mp4" -F "id=123"  "http://yii.abc.com/index.php?r=home/addfile"
        //curl -F "file1=@3.mp4" -F "在原服务器中的相对路径=files/class/g.mp4" -F "storagetime=1" -F "project=9"  -F "curl=1" "http://yii.abc.com/index.php?r=home/addfile"
        $model=new UploadForm(); //实例化一个数据
        if(Yii::$app->request->isPost){
            //p($_FILES);
            //dd($GLOBALS);//https://www.php.net/manual/zh/reserved.variables.php
            $postObj=Yii::$app->request->post();
            if(!$postObj["在原服务器中的相对路径"]){
                dd('在post对象中找到"在原服务器中的相对路径"');
            }else{
                //p($postObj["在原服务器中的相对路径"]);
                $sourcePath=trim($postObj["在原服务器中的相对路径"]); //在原服务器中的相对路径
            }//""在原服务器中的相对路径""字段存在
            if($postObj["storagetime"]){
                $deletetime=strtotime(date("Y-m-d H:i:s",strtotime("+". (int )trim($postObj["storagetime"]) ." day"))); //删除日期
            }else{
                $deletetime=strtotime(date("Y-m-d H:i:s",strtotime("+365 day")));
            }//"storagetime"字段存在
            if(strstr($sourcePath, '/')!=false){
                $filename=substr(strrchr($sourcePath,'/'),1); //截取文件名

            }else{
                $filename=$sourcePath;
            }//获取文件名字段
            if(!file_exists('uploads/')){
                mkdir('uploads',0777,true);
            }//创建保存目录
            $model->File=UploadedFile::getInstance($model,'File');//文件体
            $tmp_file="";//临时用于保存文件路径的变量
            if($model->File){
                $tmp_file=$model->File->tempName;
            }elseif(array_key_exists("file1",$_FILES)){
                $tmp_file=$_FILES["file1"]["tmp_name"];
            }else{
                return "没有上传文件";
            }//拿到临时文件路径
            $md5=md5_file($tmp_file); //文件的md5
            $filesizea=filesize($tmp_file);//统计文件大小
            $project="";
            if($postObj["project"]){
                //说明指定了项目
                $project=Project::find()->where(['id'=>$postObj["project"]])->one();
                if($project){//如果项目存在,说明上传的项目id没问题
                    //说明指定的项目id没问题
                }else{
                    dd("传的项目id错误");
                }
            }else{
                dd("没指定项目名");
            }//拿到了本次上传所属的项目对象
            if(file_exists($tmp_file)){
                //说明磁盘没满
            }else{//记录中有记录,但是硬盘中没有文件,说明磁盘满了
                dd('没有临时文件');
            }//查看临时文件是否已经位于磁盘中
            $upload=Upload::find()->where(["sourcePath"=>$sourcePath,"projectid"=>$project])->one();//查询本路径,本项目,是否有重复记录
            if($upload){//查询本路径,本项目,有重复记录,还需比较md5值,确定是不是更新文件
                if($upload->md5==$md5) {//如果newFile==oldFile,那就是传重复了:删除newFile,return error.
                    doLog("为什么会走这里面呢".$upload->md5."++++++".$md5);
                    unlink($tmp_file);
                    return "数据库中已经有一模一样的数据了,不能重复上传";
                }else{//如果newFile!=oldFile,更新upload记录,更新project记录,放置新文件,处理老文件;倒过来处理:处理老文件,放置新文件,更新project记录,更新upload记录
                    //处理老文件:老文件还有用吗?
                    doLog("难道走这里了?".$upload->md5."++++++".$md5);
                    $oldMd5UploadArray=Upload::find()->where(["md5"=>$upload->md5])->all();//md5是老文件的记录的数组是
                    doLog("oldMd5UploadArray:".count($oldMd5UploadArray));
                    $oldMd5UploadArrayDropThisUploadArray=deleteItemArray($oldMd5UploadArray,$upload);//把当前这条upload记录排除在外
                    if (count($oldMd5UploadArrayDropThisUploadArray)>0){//说明,老文件还有用:那就不能删老文件,那这个老文件也就处理完了
                        $isDeleteOldFile=false;
                    }else{//说明老文件没用了
                        unlink($upload->filepath);//到这里,老文件就处理完了
                        $isDeleteOldFile=true;
                    }
                    doLog("oldMd5UploadArrayDropThisUploadArray:".count($oldMd5UploadArrayDropThisUploadArray));
                    doLog("isDeleteOldFile:".$isDeleteOldFile);
                    //放置新文件:新文件在硬盘上有吗?
                    $newFileName=\Yii::$app->params['uploadDir'].$md5;//要放成的文件名
                    if (file_exists($newFileName)){//要放的文件在磁盘上已经存在
                        $isPutNewFile=false;
                    }else{//要放的文件在磁盘存储位置不存在
                        saveTmpFileToDisk($tmp_file,$newFileName);
                        $isPutNewFile=true;//是否修改项目的实际大小
                    }//判断要放置的文件是否在存储目录中有了,有了就不放了,没有就放
                    //更新project记录
                    $project->totalSize=$project->totalSize-$upload->size+$filesizea;
                    if($isPutNewFile){//如果你放了,说明这个文件是唯一的,那么就一定要加上新大小
                        $project->totalRealSize=$project->totalRealSize+$filesizea;
                        //至于是否要减实际大小,要看老文件是否删了,没删的话,是影响本项目还是其他项目
                        if ($isDeleteOldFile){//如果老文件被删除了,那么影响到了项目的实际小所以,要从实际大小中减去老文件的大小
                            $project->totalRealSize=$project->totalRealSize-$upload->size;
                        }else{//如果老文件没被删除,那么有可能是本项目占用了,也有可能是其他项目占用了
                            //从是老文件数组中刨除本条目后,是否还包含有本项目的记录,可以看出,是否是本项目继续占用老文件
                            $isProjectOwnThisFile="";
                            foreach ($oldMd5UploadArrayDropThisUploadArray as $otherOldUpload) {
                                if ($otherOldUpload->projectid==$project->id){
                                    $isProjectOwnThisFile=true;
                                }
                            }
                            if($isProjectOwnThisFile){//如果"是本项目继续使用这个文件"为true,那么不应该从本项目中减去实际大小
                                doLog("同一个项目的2个文件,使用了同一个md5值的文件,更新其中一个记录,项目真实大小只加不减");
                            }else{//如果"是本项目继续使用这个文件"为false,那么本项目不继续使用这个文件了,需要从本项目的实际占用中减去老文件的大小;并且给其他upload记录一个own的记录,意思是这个文件以后归它所有
                                doLog("不同项目的2个文件,使用了同一个md5值的文件,更改其中一个,如果被更改的这个是这个md5文件的所有者,那么这个被更改项目要讲这个所有者身份让出去,并从真实大小中减去老的md5文件的大小");
                                $project->totalRealSize=$project->totalRealSize-$upload->size;
                                doLog("oldMd5UploadArrayDropThisUploadArray:".count($oldMd5UploadArrayDropThisUploadArray));
                                doLog("oldMd5UploadArrayDropThisUploadArray[0]->:".$oldMd5UploadArrayDropThisUploadArray[0]->id);
                                $oldMd5UploadArrayDropThisUploadArray[0]->own=true;
                                $oldMd5UploadArrayDropThisUploadArray[0]->save();
                                $oldMd5UploadArrayDropThisUploadArray[0]->projectid;
                                $editProject=Project::find()->where(["id"=>$oldMd5UploadArrayDropThisUploadArray[0]->projectid])->one();
                                $editProject->totalRealSize=$editProject->totalRealSize+$upload->size;
                                $editProject->save();
                            }
                        }//判断是否要从实际项目大小中减去老文件大小
                    }else{
                        //没往存储目录放新文件,所以不修改项目实际存储占用空间大小
                    }
                    $project->save();
                    //更新upload记录(这里是:用户更新了文件的情况)
                    $upload->md5=$md5;
                    $upload->filepath=$newFileName;
                    $upload->deletetime=$deletetime;
                    $upload->size=$filesizea;
                    if($isPutNewFile){
                        $upload->own=true;
                    }else{
                        $upload->own=false;
                    }
                    $upload->save();
                    //处理完成返回处理模块######################
                    if(array_key_exists("curl", $_POST)){
                        return "http://".$_SERVER["HTTP_HOST"]."/index.php?r=home/get_one&id=".$upload->id."+++".$md5;
                    }else{
                        return $this->redirect('index.php?r=home/index');
                    }
                }
            }else{//查询本路径,本项目,没有重复记录
                $upload=new Upload(); //实例化一个Upload对象
                $fileStorePath=\Yii::$app->params['uploadDir'].$md5;//得到md5文件存储的位置
                if(file_exists($fileStorePath)){//如果磁盘中有这个md5文件
                    saveExistFileAndSaveMysql($tmp_file,$project,$filesizea,$upload,$filename,$fileStorePath,$md5,$sourcePath,$deletetime);
                    if(array_key_exists("curl", $_POST)){
                        return "http://".$_SERVER["HTTP_HOST"]."/index.php?r=home/get_one&id=".$upload->id."+++".$md5;
                    }else{
                        return $this->redirect('index.php?r=home/index');
                    }
                }else{//如果磁盘中没有这个md5文件
                    saveNewFileAndSaveMysql($project,$filesizea,$tmp_file,$fileStorePath,$upload,$filename,$md5,$sourcePath,$deletetime);
                    if(array_key_exists("curl", $_POST)){
                        return "http://".$_SERVER["HTTP_HOST"]."/index.php?r=home/get_one&id=".$upload->id."+++".$md5;
                    }else{
                        return $this->redirect('index.php?r=home/index');
                    }
                }
            }//就在这个if中处理存与不存记录
        }
        $projects=Project::find()->all();
        return $this->render("addFile",['model'=>$model,'projects'=>$projects]);
    }
    public function actionApiaddfile() //这个是API上传文件的过程 http://yii.abc.com/index.php?r=home/apiaddfile
    {
        //$request=\Yii::$app->request;
        //$user=$request->post('name','张三');  //张三是默认值,当没有
        //$passwd=$request->post('password','123');


        $model=new UploadForm(); //实例化一个数据
        if(Yii::$app->request->isPost){
            //$session = \Yii::$app->session;
            //$user = isset($_SESSION['user']) ? $_SESSION['user'] : null; //查询session

            //print_r($_POST);
            //dd($_FILES);
            $user=$_POST["user"];
            $sourcePath=$_POST["在原服务器中的相对路径"];  //从post请求中获得原始相对路径  //这个原始路径其实应该加上用户
            $filename=substr(strrchr($sourcePath,'/'),1); //截取文件名

            if(file_exists($_FILES['File']["tmp_name"])){ //如果临时文件存在,就保存文件和数据
                $md5=md5_file($_FILES['File']["tmp_name"]); //文件的md5
                $fileDir='uploads/'.$_POST["user"].'/'; //文件保存目录
                $filePath=$fileDir. $md5; //文件保存路径 在文件系统中存的文件都是唯一的,所以是一md5命名的

                if(!file_exists($fileDir)){
                    mkdir($fileDir,0777,true);
                }
                move_uploaded_file($_FILES['File']["tmp_name"],$filePath); //把临时文件 mv 成 md5 文件

                //尝试插入数据
                $upload=new Upload(); //实例化一个Upload对象
                $upload->filename=$filename; //这里要注意,表的字段用的不是点,而是方法的表达方式  //在数据库中文件名是可以重复的  //原始路径名是一定不能重复的
                $upload->filepath=$filePath; //文件在存储服务器的存储路径
                $upload->md5=$md5;
                $upload->sourcepath=$sourcePath; //原始路径
                //$data=$upload->insert(); //返回结果为true  这里用了insert() 方法,插入数据
                $data=$upload->save(); //save() 和 insert() 都能插入

                return '{"result":"true"}';
            }else{
                return '{"result":"false"}';
            }
        }
        return "this is apiaddfile; it need path and file.";
    }
    public function actionDoapiaddfile(){ //这是执行api上传动作的定义过程 //http://yii.abc.com/index.php?r=home/doapiaddfile
        $url='http://yii.abc.com/index.php?r=home/apiaddfile';

        $postData=array(
            'user'=>'4.1storage',
            '在原服务器中的相对路径'=>'10/a.mp4',
            'File'=> new \CURLFile(__DIR__.'\..\web\uploads\b6e0c931491ed44cd7e78678bc308d91')
        );

        $result=postFile($url,$postData); //至此,证明写的postFile函数是好用的
        dd($result);
    }
    public function actionUpload() //http://yii.abc.com/index.php?r=home/upload //这个是测试上传文件的例子
    {
        $model=new UploadForm(); //实例化一个数据
        if(Yii::$app->request->isPost){
            dd(Yii::$app->request->post());exit;
            $model->path=UploadedFile::getInstance($model,'path');
            dd($model->path);
            $model->File=UploadedFile::getInstance($model,'File');
            if($model->upload()){
                //$model->File->baseName  这个获取到不带扩展名的部分
                //$model->File->extension 这个获取到扩展名  //扩展名返回的永远是小写的
                //$model->File->name 这个可以获取文件全名
                $filename=$model->File->name;//文件名

                $filePath='uploads/' . $filename; //文件保存路径
                $md5=md5_file($filePath); //文件的md5

                //尝试插入数据
                $upload=new Upload(); //实例化一个Upload对象
                $upload->filename=$filename; //这里要注意,表的字段用的不是点,而是方法的表达方式
                $upload->filepath=$filePath;
                $upload->md5=$md5;
                //$data=$upload->insert(); //返回结果为true  这里用了insert() 方法,插入数据
                $data=$upload->save(); //save() 和 insert() 都能插入

                return $this->redirect('index.php?r=home/index');

                //$model->file->saveAs('uploads/'.$model->file->baseName.'.'.$model->file->extension );
            }
        }
        return $this->render("upload",['model'=>$model]);
    }
    public function actionBatchdelete() //http://yii.abc.com/index.php?r=home/batchdelete //这个是批量删除的路由
    {
        if(\Yii::$app->request->isPost){
            $ids_string=\Yii::$app->request->post("ids"); //获得ids
            $ids_array=explode(',',$ids_string);//字符串转数组
            foreach($ids_array as $id){
                $upload=Upload::findOne($id);
                if($upload){
                    deleteOneUpload($upload);
                }else{
                    dd('瞎几把查,又没有');
                }
            }
            return "处理完了";
        }else{
            return "请用用post方式访问";
        }
    }//这个是批量删除的路由
    public function actionBatchdeleteitem() {//这是用来跑定时任务的
        $uploads=Upload::find()->where(["<=","deletetime",time()])->all();//到了删除时间的条目
        foreach ($uploads as $upload){
            deleteOneUpload($upload);
        }
        $downloads=Download::find()->where(["<=","deletetime",time()])->all();
        foreach ($downloads as $download){
            if($download->path){
                unlink($download->path); //删除文件
            }
            $download->delete();
        }
        return "success";
    }//这是用来跑定时任务的
    public function actionEdit_one(){
        if(\Yii::$app->request->isGet){
            $id=\Yii::$app->request->get("id");
            $upload=Upload::findOne($id);
            if($upload){
                $model=new UploadForm(); //实例化一个数据
                $projects=Project::find()->all();
                return $this->render("editFile",['upload'=>$upload,"model"=>$model,"projects"=>$projects]);
            }else{
                dd('查找失败');
            }
        }
        //处理新上传的文件单元
        $tmp_file="";
        if(array_key_exists("UploadForm",$_FILES)){//这里要判断是否有这个可以key
            if(array_key_exists("tmp_name",$_FILES["UploadForm"])){
                if(array_key_exists("File",$_FILES["UploadForm"]["tmp_name"])){
                    //有上传文件,那就需要处理文件,之后处理数据即可
                    $tmp_file=$_FILES["UploadForm"]["tmp_name"]["File"];//拿到上传文件的句柄
                    if($tmp_file==''){
                        doLog("没拿到临时文件位置");
                    }else{
                        doLog("拿到临时文件位置了");
                    }
                }else{
                    dd("没检测到上传文件,请添加文件");
                }
            }else{
                dd("没检测到上传文件,请添加文件");
            }
        }else{
            dd("没检测到上传文件,请添加文件");
        }//尝试拿临时文件的位置
        if(Yii::$app->request->isPost){//如果方法是post,那么就是要改东西了
            $id=$_POST["id"];//这是数据id
            $upload = Upload::findOne($id); //实例化一个Upload对象
            if($upload){//如果这条数据真的存在
                deleteOneUpload($upload);//把原记录删除,用参数接收传值,进行存储作业即可

                $sourcePath=$_POST["在原服务器中的相对路径"];  //从post请求中获得原始相对路径  //这个原始路径其实应该加上用户
                $filename=substr(strrchr($sourcePath,'/'),1); //截取文件名
                $projectId=$_POST["project"];
                $project=Project::find()->where(["id"=>$projectId])->one();
                $deletetime = strtotime($_POST["storagetime"]); //删除时间

                if ($tmp_file){//有临时文件位置了,
                    $filesizea=filesize($tmp_file);//统计文件大小
                    $md5 = md5_file($tmp_file);//文件的md5
                    $fileStorePath=\Yii::$app->params['uploadDir'].$md5;//得到md5文件存储的位置
                    $thisMd5Files=Upload::find()->where(["md5"=>$md5])->all();//查看这个新md5值的文件在数据库中是否唯一
                    if(count($thisMd5Files)==0){//如果具有这个md5记录的记录是0条,那么这条记录应该拥有这个文件的所有权:项目实际大小要加,理论大小肯定也要加,文件数目也要加;文件也要放置
                        saveNewFileAndSaveMysql($project,$filesizea,$tmp_file,$fileStorePath,$upload,$filename,$md5,$sourcePath,$deletetime);
                        if(array_key_exists("curl", $_POST)){
                            return "http://".$_SERVER["HTTP_HOST"]."/index.php?r=home/get_one&id=".$upload->id."+++".$md5;
                        }else{
                            return $this->redirect('index.php?r=home/index');
                        }
                    }else{//如果具有这条md5记录的条目不是0条,那么这条记录不放文件,删除这个临时文件,不修改项目实际大小,修改项目理论大小,文件数目+1,upload记录即可,拥有属性为false
                        saveExistFileAndSaveMysql($tmp_file,$project,$filesizea,$upload,$filename,$fileStorePath,$md5,$sourcePath,$deletetime);
                        if(array_key_exists("curl", $_POST)){
                            return "http://".$_SERVER["HTTP_HOST"]."/index.php?r=home/get_one&id=".$upload->id."+++".$md5;
                        }else{
                            return $this->redirect('index.php?r=home/index');
                        }
                    }
                }else{
                    dd("没检测到上传文件,请添加文件");
                }//判断本次上传是否带了文件
            }else{
                return "不存在这条数据";
            }
        }
    }//这是修改一条记录时候的
    public function actionGet_one()
    {//这是获取一个记录文件的 wget 'http://ccgl_dev.36ve.com/index.php?r=home/get_one&id=115' -c -O '10. 44.wmv
        if (\Yii::$app->request->isGet) {
            $id = \Yii::$app->request->get("id"); //获得id
            $uploads=Upload::find()->where(['id'=>$id])->all();
            if(count($uploads)>0){
                $upload=$uploads[0];
                $filepath=$upload->filepath;

                //$out_filepath = 'newfilepath.mp4';
                if(\Yii::$app->params["useHdfs"]){
                    $phdfs=new \phdfs();
                    $hdfsTmpDir=Yii::$app->params["downloadHdfsDir"].time().'/';//从hdfs下载的文件临时保存的目录 //'download/hdfsTmp/2324234242
                    if (!file_exists($hdfsTmpDir)) {
                        mkdir($hdfsTmpDir, 0777, true);
                    }
                    $target=$hdfsTmpDir.'/'.$upload->filename ;//'download/hdfsTmp/2324234242/aaa.tar.gz'

                    $phdfs->get('/'.$filepath,$target);
                    Yii::$app->response->sendFile($target,$upload->filename);//文件路径,文件名
                    rmdirr($hdfsTmpDir);
                }else{//如果没有使用hdfs,就在本地文件系统查找,并发给用户
                    if( ! file_exists($filepath)){
                        dd('Not Found :' . $filepath);
                    } else {
                        $file = fopen($filepath, "r");
                        //dd(mime_content_type($filepath));
                        Yii::$app->response->sendFile($filepath,$upload->filename);//文件路径,文件名
                    }
                }
            }
        }
        return "请以get的方式访问";
    }//这是获取一个记录文件的 wget 'http://ccgl_dev.36ve.com/index.php?r=home/get_one&id=115' -c -O '10. 44.wmv
    public function actionSearch(){

        if (\Yii::$app->request->isGet) {
            $key = trim(\Yii::$app->request->get("key")); //获得key
            $selectproject=\Yii::$app->request->get("UploadForm")["selectproject"];
            //dd($selectproject);
            $uploads="";
            if((int)$selectproject==1){
                $project=Project::find()->where(['name'=>$key])->one();
                if($project){
                    $projectid=$project->id;
                    $uploads=Upload::find()->where(['projectid'=>$projectid]);//查找特定项目id下的upload条目
                }else{
                    dd('没找到');
                }
            }else{ //否则就是不按项目查找
                $uploads=Upload::find()->where(['like','sourcepath',$key]);
            }

            $model=new UploadForm();
            $projects=Project::find()->all();
            //dd(count($uploads));
            $pages=new Pagination(['totalCount'=>$uploads->count(), //http://www.manks.top/yii2_linkpager_pagination.html 分页 https://www.yiichina.com/tutorial/774
                //'pageSize' => 5,
                //'pageSizeParam' => false,
                //'pageParam' => 'p',
                //'route' => false,
                'validatePage' => false,
            ]);
            $uploads=$uploads->offset($pages->offset)->limit($pages->limit)->all();
            $data=["uploads"=>$uploads,"model"=>$model,"pages"=>$pages,"key"=>$key,"selectproject"=>$selectproject,"projects"=>$projects];
            return $this->render('index_5',$data);
        }
        return "请以get的方式访问";
    }
    public function actionProject(){
        $projects=[];
        foreach (Project::find()->batch(2) as $project ){ //foreach是循环结果  batch(2) 这是每次取N个数据  ;as 就是说,把结果赋给 $projects
            //echo count($projects),'-'; //php中的echo的多个输出值之间用逗号隔开,输出后不隔开
            $projects=array_merge($projects,$project); //它的作用是,把$article 加入$data数组,作为新元素,不拆分$articale
        }
        $model=new UploadForm();
        $data=["projects"=>$projects,"model"=>$model];
        //dd($uploads);
        return $this->render('project',$data);
    }
    public function actionAddproject() //这个是页面增加项目的过程
    {
        //$request=\Yii::$app->request;
        //$user=$request->post('name','张三');  //张三是默认值,当没有
        //$passwd=$request->post('password','123');

        $model=new UploadForm(); //实例化一个数据
        if(Yii::$app->request->isPost){
            $postObj=Yii::$app->request->post()["UploadForm"];
            //dd($postObj);
            $name=$postObj["name"]; //项目名称
            $description=$postObj["description"]; //项目描述
            $note=$postObj["note"]; //项目备注

            $projects=Project::find()->where(['name'=>$name])->all();
            if(count($projects)==0){
                //尝试插入数据
                $project=new Project(); //实例化一个Project对象
                $project->name=$name; //这里要注意,表的字段用的不是点,而是方法的表达方式
                $project->description=$description;
                $project->note=$note?$note:"空";
                //$data=$project->insert(); //返回结果为true  这里用了insert() 方法,插入数据
                $data=$project->save(); //save() 和 insert() 都能插入

                return $this->redirect('index.php?r=home/project');
            }else{
                dd('该项目已存在');
            }

            //if($model->upload()){
            //    //$model->File->baseName  这个获取到不带扩展名的部分
            //    //$model->File->extension 这个获取到扩展名  //扩展名返回的永远是小写的
            //    //$model->File->name 这个可以获取文件全名
            //    $filename=$model->File->name;//文件名
//
            //    $filePath='uploads/' . $filename; //文件保存路径
            //    $md5=md5_file($filePath); //文件的md5
//
            //    //尝试插入数据
            //    $upload=new Upload(); //实例化一个Upload对象
            //    $upload->filename=$filename; //这里要注意,表的字段用的不是点,而是方法的表达方式
            //    $upload->filepath=$filePath;
            //    $upload->md5=$md5;
            //    $upload->sourcepath=$sourcePath;
            //    //$data=$upload->insert(); //返回结果为true  这里用了insert() 方法,插入数据
            //    $data=$upload->save(); //save() 和 insert() 都能插入
//
            //    return $this->redirect('index.php?r=home/index');
//
            //    //$model->file->saveAs('uploads/'.$model->file->baseName.'.'.$model->file->extension );
            //}
        }
        return $this->render("addproject",['model'=>$model]);
    }
    public function actionEdit_projcet(){
        if(\Yii::$app->request->isGet){
            $ids_string=\Yii::$app->request->get("id"); //获得ids
            $ids_array=explode(',',$ids_string);//字符串转数组
            $id=$ids_array[0];
            $project=Project::findOne($id);
            if($project){
                //dd($project->id);
                $model=new uploadForm(); //实例化一个数据
                return $this->render("editProject",['project'=>$project,"model"=>$model]);
            }else{
                dd('查找失败');
            }
        }
        if(Yii::$app->request->isPost){
            $postObj=Yii::$app->request->post()["UploadForm"];

            $id=$postObj["id"];

            $project = project::findOne($id); //实例化一个project对象
            if($project){

                $name=trim($postObj['name']);
                $description=trim($postObj['description']);
                $note=trim($postObj['note']);

                //尝试更新数据
                $project->name = $name; //这里要注意,表的字段用的不是点,而是方法的表达方式  //在数据库中文件名是可以重复的  //原始路径名是一定不能重复的
                $project->description = $description;
                $project->note = $note;
                //$data=$project->insert(); //返回结果为true  这里用了insert() 方法,插入数据
                $data = $project->save(); //save() 和 insert() 都能插入
                return $this->redirect('index.php?r=home/project');
            }
        }
    }
    public function actionBatchdeleteproject() //http://yii.abc.com/index.php?r=home/batchdelete //这个是批量删除的路由
    {
        if(\Yii::$app->request->isPost){
            $ids_string=\Yii::$app->request->post("ids"); //获得ids

            $ids_array=explode(',',$ids_string);//字符串转数组

            foreach($ids_array as $id){
                $project=Project::findOne($id);

                if($project){
                    //项目删除之前,要把文件删除
                    $uploads=Upload::find()->where(["projectid"=>$project->id])->all();
                    foreach ($uploads as $upload) {
                        deleteOneUpload($upload);
//                        $file_uploads=Upload::find()->where(["filepath"=>$upload->filepath])->all();
//                        if(count($file_uploads)==1){
//                            if(Yii::$app->params["useHdfs"]){
//                                $phdfs=new \phdfs();
//                                $phdfs->rm('/'.$upload->filepath);
//                            }else{
//                                unlink($upload->filepath);
//                            }
//                        }
//                        $upload->delete();
                    }
                    $project->delete();
                    //p('第一个删除动作执行完毕');
                }else{
                    dd('瞎几把查,又没有');
                }
            }
            //$c=implode(',',$ids_array);//数组转字符串
            return "完成"; //表示删除干净
        }
        return "请用用post方式访问";
    }
    public function actionSearchproject(){

        if (\Yii::$app->request->isGet) {
            $key = trim(\Yii::$app->request->get("key")); //获得key
            $projects=Project::find()->where(['like','name',$key])->all();
            if(count($projects)>0){
                $model=new UploadForm();
                $data=["projects"=>$projects,"model"=>$model,"key"=>$key];
                return $this->render('project',$data);
            }
        }
        return "请以get的方式访问";
    }
    public function actionBatchdownload(){

        if(Yii::$app->request->isPost) {
            $key = trim($_POST["key"]);
            $project = Project::find()->where(['name' => $key])->one();
            if ($project) {
                $projectid = $project->id;
            } else {
                return "没找到项目名为" . $key . "的项目";
            }

            $uploads = Upload::find()->where(['projectid' => $projectid])->all();

            $tmpdir = 'uploads/' . 'download/' . time();
            $projectdir = $tmpdir . '/' . $project->name;
            //dd($projectdir);

            foreach ($uploads as $upload) {
                $filerealpath = $projectdir . '/' . $upload->sourcepath;
                $filepath = dirname($filerealpath);
                if (!file_exists($filepath)) {
                    mkdir($filepath, 0777, true);
                }
                if (file_exists($upload->filepath)) {
                    copy($upload->filepath, $filerealpath);
                    //$path = $filerealpath;
                    //$filename = $filerealpath."test.zip";
                    //$zip = new \ZipArchive();
                    //$zip->open($filename,\ZipArchive::CREATE);   //打开压缩包
                    //$zip->addFile($path,basename($path));   //向压缩包中添加文件
                    //$zip->close();  //关闭压缩包
                } else {
                    return $upload->sourcepath . "不存在于存储系统中了,可能丢失了";
                }
            }

            $zipa = new \zipa();
            try {
                //重复压缩，则会自动覆盖
                $res = $zipa->zip($projectdir, $projectdir . '.zip');
                if (!$res) {
                    dd('压缩失败');
                }
                return true;
            } catch (Exception $e) {
                dd($e->getMessage());
            }
        }
        return "请以post的方式访问";
    }
    public function actionBatchdownloada(){
        if (\Yii::$app->request->isGet) {
            $key = trim(\Yii::$app->request->get("key")); //获得key
            $selectproject=\Yii::$app->request->get("selectproject")?\Yii::$app->request->get("selectproject"):0;

            if((int)$selectproject==1){//如果是1,那就是按照项目查找的
                $project=Project::find()->where(['name'=>$key])->one();
                $projectid=$project->id;
                $uploads=Upload::find()->where(['projectid'=>$projectid])->all();//查找特定项目id下的upload条目
            }else{ //否则就是不按项目查找
                $uploads=Upload::find()->where(['like','sourcepath',$key])->all();
            }
            if($uploads){

                $filetotalsize=0;
                doLog("查询结果中有upload记录");
                foreach ($uploads as $upload){
                    $filetotalsize+=$upload->size;
                }
                doLog("filetotalsize:".$filetotalsize);
                $download=new Download();
                $deletetime=strtotime(date("Y-m-d H:i:s",strtotime("+7 day")));
                $download->key=$key;
                $download->selectproject=$selectproject;
                $download->path='暂无';
                $download->deletetime=$deletetime;
                $download->filecount=count($uploads);
                $download->filesize=$filetotalsize;
                $download->save();

                return true;
            }else{
                return "没找到";
            }
        }
        return "请以get的方式访问";
    }
    public function actionDownload(){
        $downloadId=\Yii::$app->request->get('id');
        if($downloadId){
            $downloadObj=Download::find()->where(['id'=>(int)$downloadId])->one();
            if($downloadObj){
                Yii::$app->response->sendFile($downloadObj->path);
            }
        }
        $model=new UploadForm();
        $downloads=Download::find()->all();
        $data=["model"=>$model,"downloads"=>$downloads];
        return $this->render("download",$data);
    }
    public function actionDozip(){//执行压缩任务,他是定时任务

        $tasks=Download::find()->where(['zip_percentage'=>0])->all();
        foreach ($tasks as $task){
            $task->zip_percentage=1;
            $task->save();
        }

        foreach ($tasks as $task){
            $key=$task->key; //本次下载任务的搜索关键字
            $selectproject=$task->selectproject;//是否查找项目

            $taskNowTotalSize=$task->filesize;//本次下载任务的文件总大小

            $tmpdir = 'download/' . time();//本次下载文件压缩包存放的临时目录

            if(!file_exists($tmpdir)) {
                mkdir($tmpdir,0777,true);
            }

            $zipname=$tmpdir."/".'key_'.$key.'的搜索结果.zip'; // "download/21321314/key_storage的搜索结果.zip"

            $uploads=[];
            if((int)$selectproject==1){//收集看看有哪些文件需要压缩,压缩之
                $project=Project::find()->where(['name'=>$key])->one();
                if($project){
                    $projectid=$project->id;
                    $uploads=Upload::find()->where(['projectid'=>$projectid])->all();//查找特定项目id下的upload条目
                }else{
                    dd('没找到该项目');
                }
            }else{ //否则就是不按项目查找
                $uploads=Upload::find()->where(['like','sourcepath',$key])->all();
            }

            //这就找到了全部需要压缩的文件,但是此时如果我的文件都在hdfs,就应该从hdfs拿下来再压缩之
            if(\Yii::$app->params['useHdfs'] ){//这就是用hdfs的过程
                rmdir($tmpdir);//删除用于本地存放压缩文件的目录

                $phdfs=new \Phdfs();
                //遍历$uploads
                foreach ($uploads as $upload){
                    //p($upload->filepath);
                    //p($upload->filename);

                    $source=$upload->filepath;//例如:uploads/46febd1e47404223e7294e51be98b32f
                    //$target=$postObj['target'];//就不应该传递target,因为"源的最后一位,就应该是target"

                    if(substr_compare($source,'/',-strlen('/'))==0){//如果'源'的结尾是/,说明它要的是个目录,要把最后一个/去掉,得到新的'源'
                        $source=substr($source,0,strlen($source)-1);
                    }

                    $target=substr($source,strripos($source,'/')+1);//例如:46febd1e47404223e7294e51be98b32f

                    $tmpdir = \Yii::$app->params['downloadHdfsDir']. time();//本次下载文件压缩包存放的临时目录,例如:download/hdfsTmp/1602654566
                    //$zipname=$tmpdir.'/key_'.$key.'的搜索结果.zip'; // "download/hdfsTmp/1602655842/key_4.0storage2的搜索结果.zip"; //压缩文件的目录也要是hdfs的子目录
                    $zipname=\Yii::$app->params['downloadDir'].'/key_'. time().'_'.$key.'的搜索结果.zip'; // "download/key_1602655842_4.0storage2的搜索结果.zip";

                    if(!file_exists($tmpdir))  mkdir($tmpdir,0777,true);

                    $targetTmpFile=$tmpdir.'/'.$target;//即将下载的文件的临时文件 如:download/hdfsTmp/1602654566/46febd1e47404223e7294e51be98b32f

                    if(!file_exists($targetTmpFile)){//如果文件系统中不存在目标文件,就从hdfs中提取;如果有那就别提取了
                        $result=$phdfs->get('/'.$source,$targetTmpFile);
                        if(is_string($result)){
                            if(strpos($result,'成功')){
                                $upload->filepath=$targetTmpFile;//例如:download/hdfsTmp/1602668527/46febd1e47404223e7294e51be98b32f 这是从hdfs提取下来的文件
                            }else{
                                return $result;
                            }
                        }else{
                            if(count($result)==0){
                                dd('结果是:空');
                            }
                        }
                    }

                //dd('提取成功');
                }
                zipNow($uploads,$zipname,$taskNowTotalSize,$task);
                delDirAndFile($tmpdir);
            }else{//这是不用hdfs的过程
                zipNow($uploads,$zipname,$taskNowTotalSize,$task);
            }

            $task->path=$zipname;
            $task->save();
        }
        return "批量压缩完了";
    }
    public function actionDotar(){//执行压缩任务,他是定时任务

        $tasks=Download::find()->where(['zip_percentage'=>0])->all();
        foreach ($tasks as $task){
            $task->zip_percentage=1;
            $task->save();
        }

        foreach ($tasks as $task){
            $key=$task->key; //本次下载任务的搜索关键字
            $selectproject=$task->selectproject;//是否查找项目

            $taskNowTotalSize=$task->filesize;//本次下载任务的文件总大小


            $tmpdir = 'download/' . msectime();//本次下载文件压缩包存放的临时目录
            $task->path=$tmpdir;
            $task->save();

            doLog("临时目录是:".$tmpdir);
            if(!file_exists($tmpdir)) {
                mkdir($tmpdir,0777,true);
            }

            $tarname=$tmpdir.'.tar.gz'; // "download/21321314.tar.gz"

            $uploads=[];
            if((int)$selectproject==1){//收集看看有哪些文件需要压缩,压缩之
                doLog("是要根据项目打包文件");
                $project=Project::find()->where(['name'=>$key])->one();
                if($project){
                    doLog("能找到项目在数据库中");
                    $projectid=$project->id;
                    $uploads=Upload::find()->where(['projectid'=>$projectid])->all();//查找特定项目id下的upload条目
                    doLog("文件收集完了");
                }else{
                    doLog('没找到该项目');
                    dd('没找到该项目');
                }
            }else{ //否则就是不按项目查找
                doLog("本次查找是查的单个文件");
                $uploads=Upload::find()->where(['like','sourcepath',$key])->all();
            }
            doLog("upload收集完毕");

            //这就找到了全部需要压缩的文件,但是此时如果我的文件都在hdfs,就应该从hdfs拿下来再压缩之
            if(\Yii::$app->params['useHdfs'] ){//这就是用hdfs的过程
                rmdir($tmpdir);//删除用于本地存放压缩文件的目录

                $phdfs=new \Phdfs();
                //遍历$uploads
                foreach ($uploads as $upload){
                    //p($upload->filepath);
                    //p($upload->filename);

                    $source=$upload->filepath;//例如:uploads/46febd1e47404223e7294e51be98b32f
                    //$target=$postObj['target'];//就不应该传递target,因为"源的最后一位,就应该是target"

                    if(substr_compare($source,'/',-strlen('/'))==0){//如果'源'的结尾是/,说明它要的是个目录,要把最后一个/去掉,得到新的'源'
                        $source=substr($source,0,strlen($source)-1);
                    }

                    $target=substr($source,strripos($source,'/')+1);//例如:46febd1e47404223e7294e51be98b32f

                    $tmpdir = \Yii::$app->params['downloadHdfsDir']. time();//本次下载文件压缩包存放的临时目录,例如:download/hdfsTmp/1602654566
                    //$zipname=$tmpdir.'/key_'.$key.'的搜索结果.zip'; // "download/hdfsTmp/1602655842/key_4.0storage2的搜索结果.zip"; //压缩文件的目录也要是hdfs的子目录
                    $zipname=\Yii::$app->params['downloadDir'].'/key_'. time().'_'.$key.'的搜索结果.zip'; // "download/key_1602655842_4.0storage2的搜索结果.zip";

                    if(!file_exists($tmpdir))  mkdir($tmpdir,0777,true);

                    $targetTmpFile=$tmpdir.'/'.$target;//即将下载的文件的临时文件 如:download/hdfsTmp/1602654566/46febd1e47404223e7294e51be98b32f

                    if(!file_exists($targetTmpFile)){//如果文件系统中不存在目标文件,就从hdfs中提取;如果有那就别提取了
                        $result=$phdfs->get('/'.$source,$targetTmpFile);
                        if(is_string($result)){
                            if(strpos($result,'成功')){
                                $upload->filepath=$targetTmpFile;//例如:download/hdfsTmp/1602668527/46febd1e47404223e7294e51be98b32f 这是从hdfs提取下来的文件
                            }else{
                                return $result;
                            }
                        }else{
                            if(count($result)==0){
                                dd('结果是:空');
                            }
                        }
                    }

                    //dd('提取成功');
                }
                tarNow($uploads,$tarname,$taskNowTotalSize,$task,$tmpdir);
                delDirAndFile($tmpdir);
            }else{//这是不用hdfs的过程
                tarNow($uploads,$tarname,$taskNowTotalSize,$task,$tmpdir);
            }

            $tarname=$tmpdir;     //我不需要压缩,浪费时间,只需要公布目录就行
            $task->path=$tarname; //http://ccgl.36ve.com/download/21321314/
            $task->save();
        }
        return "批量压缩完了";
    }
    public function actionDeletedownload()
    {
        $downloadId=\Yii::$app->request->post('id');
        if($downloadId){
            $downloadObj=Download::find()->where(['id'=>(int)$downloadId])->one();
            if($downloadObj){
                if(file_exists($downloadObj->path)){
                    if(\Yii::$app->params['useHdfs']){
                        rmdirr($downloadObj->path);
                        //deldir($downloadObj->path);
                    }else{
                        rmdirr($downloadObj->path);
                        //deldir($downloadObj->path);
                    }
                }

                $downloadObj->delete();
            }
            dd('success');
        }else{
            dd('没找到要删除的数据');
        }
    }

    public function actionTestshell() //测试shell的过程 http://backup.36ve.com:8083/index.php?r=home/testshell
    {
        $shell = "ls -la";
        exec($shell, $result, $status);
        $shell = "<font color='red'>$shell</font>";
        echo "<pre>";
        if( $status ){
            echo "shell命令{$shell}执行失败";
        } else {
            echo "shell命令{$shell}成功执行, 结果如下<hr>";
            print_r( $result );
        }
        echo "</pre>";
        //return $this->render("about");
    }

    public function actionPhdfs()
        //http://backup.36ve.com:8083/index.php?r=home/phdfs
    {
        if(\Yii::$app->request->isPost){
            $phdfs=new \Phdfs();
            $postObj=\Yii::$app->request->post();
            if(array_key_exists('options',$postObj)){
                $options=$postObj['options'];
            }else{
                $options='';
            }

            switch($postObj["action"]){
                case "mkdir":
                    $dir=$postObj['item'];

                    $result=$phdfs->mkdir($dir,$options);
                    dd($result);

                    break;
                case "ls":
                    $item=$postObj['item'];

                    //dd($item);
                    $result=$phdfs->ls($item,$options);
                    if(count($result)==0){
                        dd('结果是:空');
                    }
                    dd($result);
//                    $shell=$hadoop.'-mkdir' .' '. $options .' '. $item;
//
//                    exec($shell, $result, $status);
//                    $shell = "<font color='red'>$shell</font>";
//                    echo "<pre>";
//                    if( $status ){
//                        echo $status;
//                        p($result);
//                        echo "shell命令{$shell}执行失败";
//                    } else {
//                        echo "shell命令{$shell}成功执行, 结果如下<hr>";
//                        print_r( $result );
//                    }
//                    echo "</pre>";
                    break;
                case "put":
                    $source=$postObj['source'];
                    $target=$postObj['target'];
                    $result=$phdfs->put($source,$target,$options);
                    if(is_string($result)){
                        return $result;
                    }else{
                        if(count($result)==0){
                            dd('结果是:空');
                        }
                    }
                    break;
                case "get":
                    $source=$postObj['source'];
                    //$target=$postObj['target'];//就不应该传递target,因为"源的最后一位,就应该是target"

                    if(substr_compare($source,'/',-strlen('/'))==0){//如果'源'的结尾是/,说明它要的是个目录,要把最后一个/去掉,得到新的'源'
                        $source=substr($source,0,strlen($source)-1);
                    }

                    $target=substr($source,strripos($source,'/')+1);

                    $tmpdir = 'download/' . time();//本次下载文件压缩包存放的临时目录
                    if(!file_exists($tmpdir))  mkdir($tmpdir,0777,true);

                    $targetTmpdir=$tmpdir.'/'.$target;//即将下载的文件的临时目录 如:download/1602488318/ggc_hadoop-2.7.2.tar.gz

                    $result=$phdfs->get($source,$targetTmpdir);
                    if(is_string($result)){
                        if(strpos($result,'成功')){
                            return $targetTmpdir;
                        }else{
                            return $result;
                        }
                        return $result;
                    }else{
                        if(count($result)==0){
                            dd('结果是:空');
                        }
                    }

                    break;
                case "rm":
                    $source=$postObj['source'];
                    $result=$phdfs->rm($source);
                    return $result;

                    break;
                default:
                    dd(5);
            }

        }else{
            dd(2);
        }
        //dd(popen("/lhwl/app/hadoop-2.7.2/bin/hadoop fs -ls /",'r'));
        //$shell =  "/lhwl/app/hadoop-2.7.2/bin/hadoop fs -put -p -f  /lhwl/src/software /lhwl/data/hadoop/2 >> /tmp/a";
//        $shell =  'source /etc/profile && /lhwl/app/hadoop/bin/hadoop fs -rm -r /lhwl';
//        exec($shell, $result, $status);
//        $shell = "<font color='red'>$shell</font>";
//        echo "<pre>";
//        if( $status ){
//            echo $status;
//            p($result);
//            echo "shell命令{$shell}执行失败";
//        } else {
//            echo "shell命令{$shell}成功执行, 结果如下<hr>";
//            print_r( $result );
//        }
//        echo "</pre>";
//        //return $this->render("about");
    }
    public function actionGetward() //测试shell的过程 http://backup.36ve.com:8083/index.php?r=home/getward
    {
        $shell = "python zdbg.py";
        exec($shell, $result, $status);
        $shell = "<font color='red'>$shell</font>";
        // echo "<pre>";
        if( $status ){
            echo "shell命令{$shell}执行失败";
        } else {
            Yii::$app->response->sendFile("自动化日常输变配运检监测结果--报告.docx","自动化日常输变配运检监测结果--报告.docx");
            //echo "shell命令{$shell}成功执行, 结果如下<hr>";
            //print_r( $result );
        }
        //echo "</pre>";
        //return $this->render("about");
    }
    public function actionAbout()
    {
        return $this->render("about1");
    }


}

















